home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
a86v307c.arc
/
13TOOLS.DOC
< prev
next >
Wrap
Text File
|
1987-07-13
|
16KB
|
332 lines
CHAPTER 13 ASSOCIATED TOOLS 13-1
XREF Cross-reference and Symbol Listing Facility
XREF is a tool that creates a cross-referenced symbol table
listing of your program.
To invoke XREF, you must provide a program invocation line,
either typed to the console when the DOS command prompt appears,
or included in a batch file. The program invocation line
consists of the following:
1. The program name XREF.
2. The name of a symbol-table file produced by A86 when you
assembled your program. If you do not give an extension, XREF
assumes a .SYM extension; if you wish no extension, you give a
period without an extension. Note that if you follow normal
methodology, the name of the symbol-table file is the same as
the name of the program.
3. The same list of source-file names that you gave to A86. Just
as with A86, you may use the wild-card delimiters * and ? if
you wish, with the same results.
XREF, like A86, identifies the end of the source file names
when it sees a name with no extension, or a name with the
default output-extension. For XREF, that extension is .XRF.
3. You may optionally provide the word TO, to separate the source
file names from the output file names.
4. The name of the output listing file. If you do not provide an
extension, XREF will assume that you want the extension .XRF.
If you want your program file to have no extension, you end
the file name with a period.
You have the option to omit the output file name. If you do,
XREF will use the name of the symbol-table file, with the
extension .XRF.
The output of XREF is an alphabetical listing of all the non-
local symbols in your program. For each symbol, XREF gives its
type, the file in which it was defined, its value, and a list of
all procedures in which the file was used. If you print this
file, you typically use the TCOLS tool to obtain a multi-column
listing from XREF's single-column output.
Note the use of procedure names to identify references -- this is
unique to the A86 package, and makes the cross-reference listing
truly readable. Other cross-reference listings give either line
numbers, which are meaningless unless you go find the associated
line; or a file-name, which doesn't give you as much useful
information.
13-2
Here is a more detailed description of the various pieces of
information provided for each symbol:
1. TYPE. Labels are indicated by a colon immediately following
the symbol-name. Special symbols such as macro names are
denoted by an appropriate word such as "macro" in place of the
value on the following line. Other symbols types are
described by one or two characters, following the symbol name.
Possibilities for the first character are:
m for a simple memory variable
+ for an index memory quantity
c for a constant
i for an interrupt-equate
s for a structure
If there is a second letter, it is a size attribute: b for
byte, w for word, f for far (or doubleword).
2. FILE in which the symbol was defined. The name is stripped of
its extension, which is presumably the same for all your
source files. The name is preceded by = or period , which
denotes a definition, not a reference, of the symbol.
3. VALUE, given as 4 hex digits, on the line following the
symbol. For memory variables, this is the location of the
variable. For indexed quantities, this is the constant-
displacement part of the quantity. For structures, it is the
size of the structure. For interrupt-equates, it is the
number of the interrupt.
4. REFERENCES, given on indented lines following the symbol name.
All occurrences of the symbol in your program produce a
reference. If the symbol is the first thing of a line, it is
considered a "definition" of that symbol, the reference listed
is the source file name. The name is preceded by a period if
the definition was via a colon (i.e., a label); it is preceded
by an equals-sign otherwise. If the symbol is not the first
thing of the line, then it is not a definition. The
reference-listing consists of the name of the last definition
that XREF scanned (which, if your program is organized in a
standard way, will be the name of the procedure in which the
reference occurred.
Observe that you must use the local-label facility of A86 to
make this work. If you don't use local-labels as your "place-
marker" symbols, the symbol XREF gives you will often be the
name of the last "place-marker" symbol, not the name of the
last procedure.
To save space, duplicate reference-entries are denoted by a
single entry, followed by "*n", where n is the decimal number
of occurrences of that entry.
13-3
EXMAC Macro Expansion Tool
There is a tool called EXMAC which will help you troubleshoot A86
program lines that call macros. If you are not sure about what
code is being generated by your macro calls, EXMAC will tell you.
To use this tool, you must first assemble your macro definitions,
to produce a symbol-table file. If your entire program assembled
without errors, then you will already have this symbols-file; it
is usually called myprog.SYM, where "myprog" is the name of your
.COM file. If your program did not assemble correctly, the
symbol-table file will be named "fname.SYM", where fname is the
name of the source file that contained errors.
EXMAC can be used in two different ways. First, it can be used
as an interactive program. You invoke the program in this way by
typing just "EXMAC myprog", where myprog.SYM is the name of the
symbols-file. Then you can type in any number of macro-call
lines. After each line, the program will display the expanded
program text it produces. If the program does not think your
line is a macro call, it will simply echo the line back to you.
In this mode, you exit the program by typing control-Z at the
beginning of a line, then terminating the line with the ENTER
(RETURN on some computers) key. On most IBM-compatible
computers, the control-Z code is also generated by the F6 key,
for convenience.
The second way of using EXMAC is to feed a source-file to it. It
will output the equivalent source-file with the macros expanded.
You may then, if you wish, rename the new file as the original
source file, and assemble the new file. This method is useful if
you get an error on a macro expansion line, and you don't know
where the error came from. To use EXMAC in this second way, you
simply redirect standard input and output: "EXMAC myprog <in
>out". With the redirection, EXMAC will take its input from the
file "in" instead of the keyboard; and it will send its output to
the file "out" instead of the screen. (If you are not familiar
with redirection of standard input and output, you might want to
read about in Chapter 6, "Standard Input and Standard Output", of
the MS-DOS reference manual.)
13-4
A86LIB Source File Library Tool
There is a tool, A86LIB, available only if you are registered,
that lets you build libraries of source files. Here's how it
works:
First, you code and debug a source module that you want to go
into your library. Then you feed the module to A86LIB. A86LIB
enters all non-local labels and EQUates from your module into a
special dedicated file A86.LIB.
Next, you code a program that references a symbol from your
library module. When A86 assembles your program, it sees that
the symbol is undefined. A86 then looks in A86.LIB to see if
the symbol is catalogued there. If it is, A86 assembles your
library source file.
Environment Variable A86LIB
You can set an environment variable A86LIB to specify which
drives or subdirectories contain A86.LIB files. The variable
consists of a sequence of path names separated by semicolons,
just like the PATH variable used by the operating system. For
example, if you include in your AUTOEXEC.BAT file the line
SET A86LIB=C:\bin\lib;\tools\a86lib
then A86 will look for A86.LIB in the current directory, then it
will look for C:\bin\lib\A86.LIB, then \tools\a86lib\A86.LIB.
A86 will keep looking in all three library files until there are
no more undefined symbols, or there are no more source files to
assemble.
When A86 finds a symbol it needs in A86.LIB, it gets the name of
the library file containing the symbol. The library file is
assumed to be in the same directory as its A86.LIB file, unless
a complete path name (starting with \ or a drive-specifier) was
fed to A86.LIB when A86.LIB was created.
Forcing a Library Search
You may force A86 to assemble library files before moving on to
more of your program's source files. You do this by placing a
pound sign # between file names in your invocation line. For
example, suppose your program has two modules FIRST.8 and LAST.8.
FIRST.8 calls subroutines from your library; but you need the
library files assembled before LAST.8 is assembled. (You might
want this because LAST.8 allocates memory space beyond the end of
your program, which would be the end of LAST.8 if it were truly
the last module.) You accomplish this by the invocation line:
A86 FIRST.8 # LAST.8
Note that there is never any need to force a library search at
the end of your program modules: A86 always makes a library
search there, if you have any undefined symbols.
13-5
Listings with A86
A86 does not produce a .LST file, or anything similar to it! (We
now pause, to allow traditionalists to recover from their
swooning shock.) OK, everybody back to consciousness? Good.
Now let's all try to strip away our preconceptions, and look at
things with a fresh viewpoint.
In particular, let's consider what we use a listing file for, and
see how A86 meets those needs. I've been programming for 20
years; I have generated literally tons of listings.
Historically, here's what I have used listings for:
1. To find out what my error messages are. In the early days of
Intel, the text editor was so bad that it was actually faster
to march across the building and physically print the list
file, than it was to use an editor to find error messages!
But even with a fast editor, what a pain it is to go into the
list file, enduring its 120-column wide format on your 80-
column screen, copy down the errors on paper, then go back to
the source file to find where the errors were. Why doesn't
the assembler just stick the messages directly into your
source file, where you can view them and edit the source
simultaneously? That's what A86, and only A86, does.
2. To see what code was generated; those hexadecimal bytes at the
left of the listing. That was a real necessity, back in the
days of hexadecimal debuggers. There we were, furiously
patching those hex object bytes. We needed the listings to
find our way around the program, while debugging. Today, we
have symbolic, disassembling debuggers, such as D86. The
power of today's debuggers means that you seldom need to look
at hex object bytes. If you do, the debugger can show them to
you.
3. To get a symbol-table listing. The necessity of this
diminishes a great deal when you have a SYMBOLIC debugger; but
I still like to have a listing from time to time. So I have
devised a separate program, XREF, that goes through another
pass of the source file, and creates the world's finest cross-
reference listing for assemblers.
You may ask, "Why am I being forced to essentially re-assemble
my code to get a symbol table, when other assemblers will give
it to me in the original assembly?" Don't be fooled. Those
other assemblers go through all your source files twice, or
even three times. They just do it behind your back, every
time you want an assembly. That's one reason why my assembler
is so much faster than everyone else's.
13-6
4. To just look at the code. I have often in the past needed to
see that program, spread out on paper, just to get a handle on
what the program is doing. But I have needed this less and
less lately. Why? For two reasons. First, text editors have
improved. It's much, much easier than it was before to cruise
through a file on the screen. Second, my programs have
adapted to the screen-viewing methodology. Almost
subconsciously, I have started making the conceptual "chunks"
of my code fit into 1 or 2 24-line screens, rather than 1 or 2
60-line pages. This, of course, makes better, more modular
programs. (Spaghetti tends to untangle when you chop it up.)
It's gotten to the point where I can develop (and have
developed) a 5000-line application, fully debugged, without
ever making a listing!
5. For archival purposes. I still do this; you should never put
100% trust in magnetic media. But I've stripped away the
reasons for having anything but the source code and the symbol
table. So I just copy the source files and the cross-
reference listing to the printer. I haven't looked at the
listings too much; so I haven't bothered with pagination
control. If you want to, you can insert form-feeds into your
source; A86 will ignore them. Or, you can write a simple
listing-tool that recognizes the PAGE directive; A86 ignores
that directive, also.
Mimicking Tool: FAKE.EXE
As of this writing, Turbo C is aware only of the existence of
Microsoft's MASM for assembling source files it generates. I
hope to persuade Borland to provide a switch to Turbo C that
causes it to invoke A86 directly. Until that happens, I offer
the tool FAKE.EXE, that convinces Turbo C that A86 is really
MASM.
To use FAKE.EXE, it must be renamed MASM.EXE in your disk system.
I would have named it MASM myself, except that
1. Bill Gates would probably get mad at me if I did, and
2. You need to decide what to do with your real MASM if you have
it, before installing FAKE. You could either place FAKE
(named MASM.EXE) into the individual directories containing
Turbo C programs, or you can rename MASM to something like
MSM.EXE or REALMASM.EXE.
Having renamed FAKE.EXE to MASM.EXE, you may now use the Turbo
C's switch, -B, that allows you to place A86 statements into your
C program. You don't need to worry about the gory details of
what FAKE does.
13-7
If you like gory details, here they are: FAKE filters the command
line handed to it, replacing switches:
/D becomes =
/mx becomes +c
/E becomes +f
FAKE also eliminates the semicolon, appends .ASM to the source
file name, and turns on the O and S switches. It then feeds the
resulting filtered command line to A86 for assembly.
FAKE is really a COM file (MS-DOS doesn't seem to care if a COM
file is named EXE). I've named it EXE because Turbo C looks
specifically for MASM.EXE and will ignore MASM.COM.